/**
 * 文件管理模块
 * 提供文件系统操作的封装，包括读取、写入、删除文件等功能
 */

const logger = require('./logger');
const fs = wx.getFileSystemManager();
const FileManagerState = {
    IDLE: 'IDLE',
    BUSY: 'BUSY',
    ERROR: 'ERROR'
};

class FileManager {
    constructor() {
        this.state = FileManagerState.IDLE;
        this.lastError = null;
        this.userTempDir = wx.env.USER_DATA_PATH;
        logger.info('FileManager initialized', { userTempDir: this.userTempDir });
    }

    /**
     * 获取当前状态
     * @returns {string} 当前状态
     */
    getState() {
        return this.state;
    }

    /**
     * 获取最后一次错误
     * @returns {Error|null} 错误对象或null
     */
    getLastError() {
        return this.lastError;
    }

    /**
     * 重置错误状态
     */
    resetError() {
        this.lastError = null;
        this.state = FileManagerState.IDLE;
    }

    /**
     * 生成临时文件路径
     * @param {string} extension 文件扩展名，不包含点号
     * @returns {string} 临时文件完整路径
     */
    generateTempFilePath(extension = '') {
        const timestamp = Date.now();
        const random = Math.floor(Math.random() * 10000);
        const ext = extension ? `.${extension}` : '';
        return `${this.userTempDir}/temp_${timestamp}_${random}${ext}`;
    }

    /**
     * 写入文件（Promise版本）
     * @param {string} filePath 文件路径
     * @param {string|ArrayBuffer} data 文件数据
     * @param {string} [encoding='utf8'] 编码方式
     * @returns {Promise<string>} 成功时返回文件路径
     */
    writeFile(filePath, data, encoding = 'utf8') {
        this.state = FileManagerState.BUSY;

        return new Promise((resolve, reject) => {
            fs.writeFile({
                filePath,
                data,
                encoding,
                success: () => {
                    this.state = FileManagerState.IDLE;
                    logger.debug('File written successfully', { filePath });
                    resolve(filePath);
                },
                fail: (err) => {
                    this.state = FileManagerState.ERROR;
                    this.lastError = err;
                    logger.error('Failed to write file', { filePath, error: err });
                    reject(err);
                }
            });
        });
    }

    /**
     * 读取文件（Promise版本）
     * @param {string} filePath 文件路径
     * @param {string} [encoding='utf8'] 编码方式
     * @returns {Promise<string|ArrayBuffer>} 文件内容
     */
    readFile(filePath, encoding = 'utf8') {
        this.state = FileManagerState.BUSY;

        return new Promise((resolve, reject) => {
            fs.readFile({
                filePath,
                encoding,
                success: (res) => {
                    this.state = FileManagerState.IDLE;
                    logger.debug('File read successfully', { filePath });
                    resolve(res.data);
                },
                fail: (err) => {
                    this.state = FileManagerState.ERROR;
                    this.lastError = err;
                    logger.error('Failed to read file', { filePath, error: err });
                    reject(err);
                }
            });
        });
    }

    /**
     * 删除文件（Promise版本）
     * @param {string} filePath 文件路径
     * @returns {Promise<void>}
     */
    deleteFile(filePath) {
        this.state = FileManagerState.BUSY;

        return new Promise((resolve, reject) => {
            fs.unlink({
                filePath,
                success: () => {
                    this.state = FileManagerState.IDLE;
                    logger.debug('File deleted successfully', { filePath });
                    resolve();
                },
                fail: (err) => {
                    this.state = FileManagerState.ERROR;
                    this.lastError = err;
                    logger.error('Failed to delete file', { filePath, error: err });
                    reject(err);
                }
            });
        });
    }

    /**
     * 将Base64数据写入文件
     * @param {string} base64Data Base64编码的数据 (可以带前缀也可以不带)
     * @param {string} [extension=''] 文件扩展名
     * @returns {Promise<string>} 成功时返回文件路径
     */
    saveBase64ToFile(base64Data, extension = '') {
        // 移除可能存在的 Base64 前缀 (如 "data:audio/wav;base64,")
        const dataStart = base64Data.indexOf('base64,');
        const pureSata = dataStart >= 0 ? base64Data.substring(dataStart + 7) : base64Data;

        try {
            // 将base64转换为ArrayBuffer
            const fileContent = wx.base64ToArrayBuffer(pureSata);
            const tempFilePath = this.generateTempFilePath(extension);

            return this.writeFile(tempFilePath, fileContent, 'binary');
        } catch (error) {
            this.state = FileManagerState.ERROR;
            this.lastError = error;
            logger.error('Failed to save base64 to file', { error });
            return Promise.reject(error);
        }
    }

    /**
     * 检查文件是否存在
     * @param {string} filePath 文件路径
     * @returns {Promise<boolean>} 是否存在
     */
    fileExists(filePath) {
        return new Promise((resolve) => {
            fs.access({
                path: filePath,
                success: () => resolve(true),
                fail: () => resolve(false)
            });
        });
    }

    /**
     * 获取文件信息
     * @param {string} filePath 文件路径
     * @returns {Promise<Object>} 文件信息对象
     */
    getFileInfo(filePath) {
        return new Promise((resolve, reject) => {
            fs.getFileInfo({
                filePath,
                success: (res) => {
                    logger.debug('Got file info', { filePath, size: res.size });
                    resolve(res);
                },
                fail: (err) => {
                    this.lastError = err;
                    logger.error('Failed to get file info', { filePath, error: err });
                    reject(err);
                }
            });
        });
    }

    /**
     * 复制文件
     * @param {string} srcPath 源文件路径
     * @param {string} destPath 目标文件路径
     * @returns {Promise<void>}
     */
    copyFile(srcPath, destPath) {
        this.state = FileManagerState.BUSY;

        return new Promise((resolve, reject) => {
            fs.copyFile({
                srcPath,
                destPath,
                success: () => {
                    this.state = FileManagerState.IDLE;
                    logger.debug('File copied successfully', { from: srcPath, to: destPath });
                    resolve();
                },
                fail: (err) => {
                    this.state = FileManagerState.ERROR;
                    this.lastError = err;
                    logger.error('Failed to copy file', { from: srcPath, to: destPath, error: err });
                    reject(err);
                }
            });
        });
    }

    /**
     * 将网络文件下载到本地临时路径
     * @param {string} url 文件网络地址
     * @param {string} [extension=''] 文件扩展名
     * @returns {Promise<string>} 下载后的本地文件路径
     */
    downloadFile(url, extension = '') {
        const tempFilePath = this.generateTempFilePath(extension);

        return new Promise((resolve, reject) => {
            wx.downloadFile({
                url,
                filePath: tempFilePath,
                success: (res) => {
                    if (res.statusCode === 200) {
                        logger.debug('File downloaded successfully', { url, tempFilePath });
                        resolve(tempFilePath);
                    } else {
                        const error = new Error(`Download failed with status code: ${res.statusCode}`);
                        this.lastError = error;
                        logger.error('Download failed', { url, statusCode: res.statusCode });
                        reject(error);
                    }
                },
                fail: (err) => {
                    this.lastError = err;
                    logger.error('Download failed', { url, error: err });
                    reject(err);
                }
            });
        });
    }
}

// 导出单例
const fileManager = new FileManager();
module.exports = fileManager; 